package com.example.rwq_test.aqs;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description
 *  1. lock()方法是一个阻塞方法，它会一直等待直到获取到锁为止。如果无法获取锁，线程将被阻塞直到获取到锁为止。
 *  2. tryLock()方法是一个非阻塞方法，它会尝试获取锁但不会等待。如果无法获取锁，它会立即返回一个布尔值来表示是否获取到了锁。
 *  3. tryLock(long, java.util.concurrent.TimeUnit) 会尝试一段时间内的在返回
 *  4. 锁【lock.lock】必须紧跟try代码块，且unlock要放到finally第一行。
 *      4.1 在使用阻塞等待获取锁的方式中，必须在try代码块之外，并且在加锁方法与try代码块之间没有任何可能抛出异常的方法调用，避免加锁成功后，在finally中无法解锁。
 *      4.2 说明一：如果在lock方法与try代码块之间的方法调用抛出异常，那么无法解锁，造成其它线程无法成功获取锁。
 *      4.3 说明二：如果lock方法在try代码块之内，可能由于其它方法抛出异常，导致在finally代码块中，unlock对未加锁的对象解锁，它会调用AQS的tryRelease方法（取决于具体实现类），抛出IllegalMonitorStateException异常。
 *      4.4 说明三：在Lock对象的lock方法实现中可能抛出unchecked异常，产生的后果与说明二相同。
 *  5. tryLock();和 tryLock(2, TimeUnit.SECONDS);这两个没有具体位置要求，但个人认为最好放在try里。
 * @Author renweiqiang
 * @Date 2024/5/11 下午2:30
 */
public class ReentrantLockDemo {


    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        // lock.lock() 必须放在try外并且紧挨着try才行. 详解如上述
        lock.lock();
        try {

            lock.tryLock();

            lock.tryLock(2, TimeUnit.SECONDS);
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }
    }
}
